package com.dynasty;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @description 多线程
 * Created by wangchao12 on 2019/4/24 19:45.
 */

public class MultipleThreadPrint {
    private static int status = 1;
    private static int n = 1;

    /**
     * 方法的功能描述：启动三个线程打印递增的数字，线程1先打印1、2、3，然后线程2打印4,5,6，然后线程3
     * 打印7、8、9，接着再由线程1打印10、11、12。。。。。。以此类推，直到打印75
     *
     * @param
     * @return
     */
    private void printDigital1(final MultipleThreadPrint multipleThread) {
        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 9; i++) {
                    synchronized (multipleThread) {
                        while (1 != status) {
                            try {
                                multipleThread.wait();
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                        for (int j = 0; j < 3; j++) {
                            System.out.println(Thread.currentThread().getName() + "  " + n);
                            n++;
                        }
                        status = 2;
                        multipleThread.notifyAll();
                    }
                }
            }
        }, "thread1");
        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 8; i++) {
                    synchronized (multipleThread) {
                        while (2 != status) {
                            try {
                                multipleThread.wait();
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                        for (int j = 0; j < 3; j++) {
                            System.out.println(Thread.currentThread().getName() + "  " + n);
                            n++;
                        }
                        status = 3;
                        multipleThread.notifyAll();
                    }
                }
            }
        }, "thread2");
        Thread thread3 = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 8; i++) {
                    synchronized (multipleThread) {
                        while (3 != status) {
                            try {
                                multipleThread.wait();
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                        for (int j = 0; j < 3; j++) {
                            System.out.println(Thread.currentThread().getName() + "  " + n);
                            n++;
                        }
                        status = 1;
                        multipleThread.notifyAll();
                    }
                }
            }
        }, "thread3");
        thread1.start();
        thread2.start();
        thread3.start();
    }

    /** 使用lock做锁 **/
    private ReentrantLock lock = new ReentrantLock();
    /** 获得lock锁的3个分支条件 **/
    private Condition c1 = lock.newCondition();
    private Condition c2 = lock.newCondition();
    private Condition c3 = lock.newCondition();
    /**
     * 方法的功能描述：启动三个线程打印递增的数字，线程1先打印1、2、3，然后线程2打印4,5,6，然后线程3
     * 打印7、8、9，接着再由线程1打印10、11、12。。。。。。以此类推，直到打印75
     *
     * @param
     * @return
     */
    private void printDigital2() {
        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 9; i++) {
                    try {
                        lock.lock();
                        while (1 != status) {
                            c1.await();
                        }
                        for (int j = 0; j < 3; j++) {
                            System.out.println(Thread.currentThread().getName() + "  " + n);
                            n++;
                        }
                        status = 2;
                        c2.signal();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } finally {
                        lock.unlock();
                    }
                }
            }
        }, "thread1");
        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 8; i++) {
                    try {
                        lock.lock();
                        while (2 != status) {
                            c2.await();
                        }
                        for (int j = 0; j < 3; j++) {
                            System.out.println(Thread.currentThread().getName() + "  " + n);
                            n++;
                        }
                        status = 3;
                        c3.signal();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } finally {
                        lock.unlock();
                    }
                }
            }
        }, "thread2");
        Thread thread3 = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 8; i++) {
                    try {
                        lock.lock();
                        while (3 != status) {
                            c3.await();
                        }
                        for (int j = 0; j < 3; j++) {
                            System.out.println(Thread.currentThread().getName() + "  " + n);
                            n++;
                        }
                        status = 1;
                        c1.signal();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } finally {
                        lock.unlock();
                    }
                }
            }
        }, "thread3");
        thread1.start();
        thread2.start();
        thread3.start();
    }

    public static void main(String[] args) {
        MultipleThreadPrint multipleThread = new MultipleThreadPrint();
        multipleThread.printDigital1(multipleThread);
        //multipleThread.printDigital2();
    }
}
